package com.interview.a_多线程.e_Thread和Object中的重要方.b_Wait_NotifyAll;

/**
 * 展示  Wait 和 notifyAll 基本用法
 * <p>
 * 实现：三个线程 1 2 首先被阻塞  3去唤醒它们
 * <p>
 * 证明：start 先执行 不代表会先启动
 */
public class WaitNotifyAll {

    public static Object resource = new Object();

    static class Thread1 extends Thread {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " 进入RUN方法 想要获取锁");
            synchronized (resource) {
                System.out.println(Thread.currentThread().getName() + " 取锁成功");
                try {
                    System.out.println(Thread.currentThread().getName() + " 带着锁休息5秒... \n\n");
                    Thread.sleep(5000);
                    System.out.println("\n" + Thread.currentThread().getName() + " 休息完成 释放锁 并开始等待被唤醒....\n\n");
                    resource.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(Thread.currentThread().getName() + " 被唤醒 操作结束.");
            }
        }
    }

    static class Thread2 extends Thread {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " 进入RUN方法 想要获取锁");
            synchronized (resource) {
                System.out.println(Thread.currentThread().getName() + " 取锁成功");
                try {
                    System.out.println(Thread.currentThread().getName() + " 带着锁休息5秒... \n\n");
                    Thread.sleep(5000);
                    System.out.println("\n" + Thread.currentThread().getName() + " 休息完成 释放锁 并开始等待被唤醒....\n\n");
                    resource.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(Thread.currentThread().getName() + " 被唤醒，操作结束.");
            }
        }
    }

    static class Thread3 extends Thread {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " 进入RUN方法 想要获取锁");
            synchronized (resource) {
//                resource.notify();
//                System.out.println(Thread.currentThread().getName() + "取锁成功，执行了唤醒 notify（）");

                resource.notifyAll();
                System.out.println(Thread.currentThread().getName() + "取锁成功，执行了唤醒notifyAll（）");
            }
        }
    }


    public static void main(String[] args) throws InterruptedException {
        Thread1 thread1 = new Thread1();
        thread1.start();
        thread1.setName("线程1");

        Thread2 thread2 = new Thread2();
        thread2.setName("线程2");
        thread2.start();

        Thread.sleep(15000);
        Thread3 thread3 = new Thread3();
        thread3.setName("线程3");
        thread3.start();

    }
}

